package com.lm.rdf4j.service;

import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.sail.SailRepository;
import org.eclipse.rdf4j.sail.memory.MemoryStore;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Service
public class FraudDetectionService {

    private Repository repository;

    @PostConstruct
    public void init() {
        // 使用内存存储库初始化 RDF 数据（实际项目可使用持久化存储）
        repository = new SailRepository(new MemoryStore());
        repository.init();

        try (RepositoryConnection conn = repository.getConnection()) {
            // 模拟数据加载
            // 用户A, 用户B 均使用同一个设备
            String ns = "http://example.org/";
            conn.add(conn.getValueFactory().createIRI(ns, "UserA"),
                    conn.getValueFactory().createIRI(ns, "usedDevice"),
                    conn.getValueFactory().createIRI(ns, "DeviceX"));
            conn.add(conn.getValueFactory().createIRI(ns, "UserB"),
                    conn.getValueFactory().createIRI(ns, "usedDevice"),
                    conn.getValueFactory().createIRI(ns, "DeviceX"));
        }
    }

    public List<String> detectFraudulentUsers() {
        List<String> fraudUsers = new ArrayList<>();
        try (RepositoryConnection conn = repository.getConnection()) {
            // SPARQL 查询：查找使用相同设备的用户
            String queryString = "PREFIX ex: <http://example.org/> " +
                    "SELECT ?device (GROUP_CONCAT(?user; separator=\",\") AS ?users) " +
                    "WHERE { ?user ex:usedDevice ?device . } " +
                    "GROUP BY ?device " +
                    "HAVING (COUNT(?user) > 1)";  // 超过1个用户使用同一设备
            TupleQuery query = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
            try (TupleQueryResult result = query.evaluate()) {
                result.forEach(bindingSet -> {
                    String users = bindingSet.getValue("users").stringValue();
                    fraudUsers.add(users);
                });
            }
        }
        return fraudUsers;
    }
}